
'''
InvoiceToPDF.py
This program shows how to convert invoice data from
Python data structures into a PDF invoice.
Author: Vasudev Ram
Copyright 2015 Vasudev Ram
'''

import sys
import time
from PDFWriter import PDFWriter

def error_exit(message):
    sys.stderr.write(message)
    sys.exit(1)

def InvoiceToPDF(pdf_filename, data):
    try:
        # Get the invoice data from the dict.
        font_name = data['font_name']
        font_size = data['font_size']
        header = data['header']
        footer = data['footer']
        invoice_number = data['invoice_number']
        invoice_customer = data['invoice_customer']
        invoice_date_time = data['invoice_date_time']
        invoice_line_items = data['invoice_line_items']
    except KeyError as ke:
        error_exit("KeyError: {}".format(ke))
    try:
        with PDFWriter(pdf_filename) as pw:
            # Generate the PDF invoice from the data.
            pw.setFont(font_name, font_size)
            pw.setHeader(header)
            pw.setFooter(footer)
            pw.writeLine('-' * 60)
            pw.writeLine('Invoice Number: ' + str(invoice_number))
            pw.writeLine('Invoice Customer: ' + invoice_customer)
            pw.writeLine('Invoice Date & Time: ' + invoice_date_time)
            pw.writeLine('-' * 60)
            pw.writeLine('Invoice line items:')
            pw.writeLine('S. No.'.zfill(5) + ' ' + 'Description'.ljust(10) + \
            ' ' + 'Unit price'.ljust(10) + ' ' + 'Quantity'.ljust(10) + ' ' + \
            str('Ext. Price').rjust(8))
            pw.writeLine('-' * 60)
            sum_ext_price = 0
            for line_item in invoice_line_items:
                id, desc, price, quantity = line_item
                pw.writeLine(str(id).zfill(5) + ' ' + desc.ljust(10) + \
                ' ' + str(price).rjust(10) + ' ' + str(quantity).rjust(10) + \
                str(price * quantity).rjust(10))
                sum_ext_price += price * quantity
            pw.writeLine('-' * 60)
            pw.writeLine('Total:'.rjust(38) + str(sum_ext_price).rjust(10))
            pw.writeLine('-' * 60)
    except IOError as ioe:
        error_exit("IOError: {}".format(ioe))
    except Exception as e:
        error_exit("Exception: {}".format(e))

def testInvoiceToPDF(pdf_filename):
    # Get the Unix-style date from the system ...
    cdt = time.ctime(time.time()).split()
    # ... and format it a little differently.
    current_date_time = cdt[0] + ' ' + cdt[1] + ' ' + cdt[2] + \
    ', ' + cdt[4] + ', ' + cdt[3][:5]
    data = { \
        'font_name': 'Courier', \
        'font_size': 12, \
        'header': 'Customer Invoice', \
        'footer': 'Generated by xtopdf: http://bit.ly/xtopdf', \
        'invoice_number': 12345, \
        'invoice_customer': 'Mr. Vasudev Ram', \
        'invoice_date_time': current_date_time, \
        'invoice_line_items': \
        [
            [ 01, 'Chair', 100, 10 ], \
            [ 02, 'Table', 200, 20 ], \
            [ 03, 'Cupboard', 300, 30 ], \
            [ 04, 'Bed', 400, 40 ], \
            [ 05, 'Wardrobe', 500, 50 ], \
        ]
    }
    InvoiceToPDF(pdf_filename, data)
    
def main():
    if len(sys.argv) != 2:
        error_exit("Usage: {} pdf_filename".format(sys.argv[0]))
    testInvoiceToPDF(sys.argv[1]) 

if __name__ == '__main__':
    main()

